package com.umeox.watch.moto.launcher.ui;

import static com.umeox.watch.moto.pedometer.util.ICache.KEY_GUIDE;

import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.umeox.moto.common.encrypt.CryptoUtil;
import com.umeox.moto.common.log.Logger;
import com.umeox.moto.common.utils.AndroidUtils;
import com.umeox.moto.watch.themes.app.ThemeAppCompatActivity;
import com.umeox.moto.watch.themes.util.UToast;
import com.umeox.moto.watch.themes.widget.TextView;
import com.umeox.watch.moto.dataservice.DataProvider;
import com.umeox.watch.moto.dataservice.proxy.PushApiClientProxy;
import com.umeox.watch.moto.launcher.BuildConfig;
import com.umeox.watch.moto.launcher.R;
import com.umeox.watch.moto.launcher.constant.Constant;
import com.umeox.watch.moto.launcher.utils.ZXingUtils;
import com.umeox.watch.moto.pedometer.util.CacheImpl;
import com.umeox.watch.moto.pedometer.util.ICache;

public class QrActivity extends ThemeAppCompatActivity {

    private static final String TAG = QrActivity.class.getSimpleName();
    private static final String KEY_LAST_TIME_FETCH_CODE = "last_time_fetch_code";
    private static final int MSG_GO_TO_MAIN = 0x11;
    private static final int MSG_GET_DEVICE_CONFIG = 0x12;

    private ImageView qrImg;
    private TextView tvBindCode;
    private LinearLayout mBindSuccessLl;
    private String qrCode;

    private BindReceiver mBindReceiver;
    private TextView mSkipTv;


    private PushApiClientProxy apiClientProxy;

    private final ContentObserver mDeviceCodeObserver = new DeviceCodeContentObserver();

    public static void launch(Context context) {
        Intent intent = new Intent(context, QrActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

    private PushApiClientProxy getApiClientProxy() {
        if (apiClientProxy == null) {
            apiClientProxy = (PushApiClientProxy) PushApiClientProxy.fetchBinder();
        }
        return apiClientProxy;
    }


    private class DeviceCodeContentObserver extends ContentObserver {

        public DeviceCodeContentObserver() {
            super(new Handler());
        }

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            qrCode = DataProvider.getQrCode();
            Logger.e(TAG, "DeviceCodeContentObserver,qrCode=" + qrCode);
            createCode(qrCode, qrImg);
            UToast.show(getResources().getString(R.string.qrcode_refreshed_str), Toast.LENGTH_SHORT);
        }

    }


    private final Handler mHandler = new Handler(new Handler.Callback() {
        @SuppressLint("WrongConstant")
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            if (msg.what == MSG_GO_TO_MAIN) {
                final ICache iCache = CacheImpl.getInstance();
                if (!iCache.get(KEY_GUIDE, false)) {
                    Intent intent = new Intent(QrActivity.this, GuideActivity.class);
                    intent.putExtra("is_done_finish", false);
                    startActivity(intent);
                    finish();
                    return true;
                }

                QrActivity.this.startActivity(new Intent(QrActivity.this, MainActivity.class));
                QrActivity.this.finish();
            } else if (msg.what == MSG_GET_DEVICE_CONFIG) {
                try {
                    getApiClientProxy().deviceConfig();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
            return false;
        }
    });


    @SuppressLint("WrongConstant")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        super.onCreate(savedInstanceState);
        Logger.e("=========QrActivity onCreate===========");
        setContentView(R.layout.qr_activity);

        qrImg = findViewById(R.id.qrImg);
        tvBindCode = findViewById(R.id.tv_bind_code);
        mBindSuccessLl = findViewById(R.id.bind_success_ll);
        mSkipTv = findViewById(R.id.skip_tv);
        DataProvider.DeviceCodeProvider.registerContentObserver(true, mDeviceCodeObserver);
        registerBindReceiver();
        fetchBindCode();

        mSkipTv.setOnClickListener(v -> {
            startActivity(new Intent(QrActivity.this, MainActivity.class));
            QrActivity.this.finish();
        });
        qrImg.setOnClickListener(v -> {
            if ((System.currentTimeMillis() - CacheImpl.getInstance().get(KEY_LAST_TIME_FETCH_CODE, 0L)) > 5000) {
                try {
                    getApiClientProxy().requestGetBindCode();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                CacheImpl.getInstance().put(KEY_LAST_TIME_FETCH_CODE, System.currentTimeMillis());
            }
        });
    }

    private void fetchBindCode() {
        ContentValues deviceCode = DataProvider.getDeviceCode(AndroidUtils.getDeviceId());
        if (deviceCode == null) {
            //直接获取
            Logger.e(TAG, "本地deviceCode为空");
            requestBindCodeFromServer();
        } else {
            long expiredTime = deviceCode.getAsLong(DataProvider.DeviceCodeProvider.EXPIRED_TIME);
            if (System.currentTimeMillis() / 1000 > expiredTime) {
                requestBindCodeFromServer();
            } else {
                String qrCode = deviceCode.getAsString(DataProvider.DeviceCodeProvider.QR_CODE);
                Logger.e(TAG, "fetchBindCode from DB,qrCode=" + qrCode);
                createCode(qrCode, qrImg);
            }
        }
    }

    private void requestBindCodeFromServer() {
        try {
            //generateQrCodeByLocal();
            getApiClientProxy().requestGetBindCode();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    private void generateQrCodeByLocal() {
        Logger.e(TAG, "即将生成本地二维码");
        //f=d&code=xxx
        // deviceNamexxxxxxxxxxxxxxxproductKeyxxxxxxxxxxx
        String stringForSignature = "deviceName" + AndroidUtils.getDeviceId() + "productKey" + BuildConfig.PRODUCT_KEY;
        String cryptoStr;
        try {
            cryptoStr = CryptoUtil.hmacMd5(stringForSignature, BuildConfig.PRODUCT_SECRET);
            Logger.i("cryptoStr=" + cryptoStr);
            String qrCode = "f=" + BuildConfig.DATA_FROM + "&code=" + cryptoStr.substring(8, 24).toLowerCase() + AndroidUtils.getDeviceId();
            createCode(qrCode, qrImg);
        } catch (Exception e) {
            e.printStackTrace();
            Logger.i("hmacMd5 加密报错");
        }
    }

    private void registerBindReceiver() {
        mBindReceiver = new BindReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Constant.IntentConstant.INTENT_ACTIVE);
        intentFilter.addAction(Constant.IntentConstant.MQTT_CONNECTED);
        registerReceiver(mBindReceiver, intentFilter);
    }


    public void createCode(String info, ImageView view) {
        if (info == null) {
            return;
        }
        Bitmap codeBitmap;
        try {
            codeBitmap = ZXingUtils.createQRCode(info, 100, 100);
            view.setImageBitmap(codeBitmap);
            tvBindCode.setText(getString(R.string.k2_invite_follower_binding_code, info));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onDestroy() {
        Logger.e("=========QrActivity onDestroy===========");
        super.onDestroy();
        if (mDeviceCodeObserver != null) {
            getContentResolver().unregisterContentObserver(mDeviceCodeObserver);
        }
        if (mBindReceiver != null) {
            unregisterReceiver(mBindReceiver);
            mBindReceiver = null;
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (keyCode == KeyEvent.KEYCODE_BACK) {
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }


    private class BindReceiver extends BroadcastReceiver {

        @SuppressLint("WrongConstant")
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (TextUtils.isEmpty(action)) {
                return;
            }
            Logger.e("action:" + action);

            if (action.equals(Constant.IntentConstant.INTENT_ACTIVE)) {
                mBindSuccessLl.setVisibility(View.VISIBLE);
                mHandler.sendEmptyMessageDelayed(MSG_GO_TO_MAIN, 1000);
            } else if (action.equals(Constant.IntentConstant.MQTT_CONNECTED)) {
                try {
                    getApiClientProxy().requestGetBindCode();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                mHandler.sendEmptyMessageDelayed(MSG_GET_DEVICE_CONFIG, 3000);
            }
        }
    }

    @Override
    protected void registerUnbindAndDisableReceiver(boolean register) {
    }
}
